package com.closeenough.app;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.ContactsContract.CommonDataKinds.Email;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.drawable.Drawable;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;

public class MainWindowActivity extends MapActivity {

	private final LocationListener locationListener = new LocationListener() {
		// TODO: en estos handlers se deberia controlar si es momento de
		// disparar la alarma
		public void onLocationChanged(Location location) {
			Log.d("le debug", "Location changed");
			updateWithNewLocation(location, false);
		}

		public void onProviderDisabled(String provider) {
			Log.d("le debug", "Provider disabled");
			updateWithNewLocation(null, false);
		}

		public void onProviderEnabled(String provider) {
		}

		public void onStatusChanged(String provider, int status, Bundle extras) {
		}
	};

	public LocationManager locationManager;
	private String locationProvider;
	private MarkersOverlay markersOverlay;
	private static final String PROX_ALERT_INTENT = "com.closeenough.app";
	private String notificationTitle;
	private String notificationDescription;
	private String answerEmail = "";
	
	private PendingIntent currentMeetingIntent;

	private MapView mapView;
	
	@Override
	protected boolean isRouteDisplayed() {
		return false;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mapView = (MapView) findViewById(R.id.myMapView);

		configureLocationManager();
		configureLocationListener();
		configureMapView();

		notificationTitle = getString(R.string.notification_title);
		notificationDescription = getString(R.string.notification_text);

		mapView.invalidate();

		
		if(getIntent().getData()!= null){
			openInvitation();
		}		
	}
	
	private void openInvitation() {
		Uri uri = getIntent().getData();
		InputStream is = null;
		try {
			is = getContentResolver().openInputStream(uri);
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}		
		BufferedReader r = new BufferedReader(new InputStreamReader(is));
		StringBuilder total = new StringBuilder();
		String line;
		try {
			while ((line = r.readLine()) != null) {
			    total.append(line);
			}
		} catch (IOException e) {
			Log.d("le debug", "fugly error reading invitation");
		}
		String[] data = total.toString().split(",");
		Log.d("le debug", total.toString());
		Log.d("le debug", data.length + "");
		setMeeting(data);
	}

	private void setMeeting(String[] data) {
		GeoPoint p = new GeoPoint(Integer.parseInt(data[0]), Integer.parseInt(data[1]));
		answerEmail = data[3];
		markersOverlay.updateMeetingMarker(p);
	}

	private void configureLocationListener() {
		locationManager.requestLocationUpdates(locationProvider, 2000, 10,
				locationListener);
	}

	private void configureLocationManager() {
		String context = Context.LOCATION_SERVICE;
		locationManager = (LocationManager) getSystemService(context);

		// Criterio para seleccionar el mejor proveedor de Geo
		Criteria criteria = new Criteria();
		criteria.setAccuracy(Criteria.ACCURACY_FINE);
		criteria.setAltitudeRequired(false);
		criteria.setBearingRequired(false);
		criteria.setCostAllowed(true);
		criteria.setPowerRequirement(Criteria.POWER_LOW);
		locationProvider = locationManager.getBestProvider(criteria, true);
		updateWithNewLocation(
				locationManager.getLastKnownLocation(locationProvider), true);
		locationManager.requestLocationUpdates(locationProvider, 2000, 10,
				locationListener);
	}

	private void configureMapView() {
		// map display options
		mapView.setSatellite(false);
		mapView.setBuiltInZoomControls(true);

		// Drawable redBalloon =
		// this.getResources().getDrawable(R.drawable.reddot);
		Drawable blueBalloon = this.getResources().getDrawable(
				R.drawable.bluedot);
		markersOverlay = new MarkersOverlay(blueBalloon, this);

		mapView.getOverlays().add(markersOverlay);
	}

	public void addProximityAlert(GeoPoint p) {
		Intent intent = new Intent(PROX_ALERT_INTENT);
		currentMeetingIntent = PendingIntent.getBroadcast(this, 0,
				intent, 0);
		//TODO: hay un bug aca. Al cambiar en settings el radio default se vuelve a dibujar
		//el mapa con el radio nuevo. Pero el proximity alert tiene el radio viejo.
		//es un error muy sutil. Tranquilamente podria quedar en la version final.
		SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
		int meetingRadius = Integer.parseInt(sharedPref.getString("radius", "500"));

		locationManager.addProximityAlert((double) p.getLatitudeE6() / 1E6,
				(double) p.getLongitudeE6() / 1E6, meetingRadius, -1,
				currentMeetingIntent);
		IntentFilter filter = new IntentFilter(PROX_ALERT_INTENT);
		registerReceiver(new ProximityIntentReceiver(notificationTitle,notificationDescription, answerEmail ), filter);
		//clears the answer email, if it had any data.
		answerEmail = "";
	}

	@Override
	/* Creo el menu */
	public boolean onCreateOptionsMenu(Menu menu) {
		getMenuInflater().inflate(R.menu.activity_main, menu);
		return true;
	}

	public boolean onOptionsItemSelected(MenuItem item) {
		if (item.getItemId() == R.id.menu_about) 
		{
			startActivity(new Intent(this, AboutInfo.class));
		} 
		else if (item.getItemId() == R.id.menu_settings) 
		{
			startActivity(new Intent(this, SettingsActivity.class));
		}
		else if (item.getItemId() == R.id.menu_invitation && markersOverlay.hasMeetingPoint())
		{
			
		}
		else if (item.getItemId() == R.id.menu_invitation) 
		{
			GeoPoint gp = markersOverlay.getMeetingGeoPoint();
			Intent i = new Intent(this, InvitationSender.class);
			Bundle b = new Bundle();
			b.putInt("latitude", gp.getLatitudeE6());
			b.putInt("longitude", gp.getLongitudeE6());
			i.putExtras(b);
			try{
				startActivity(i);
			}
			catch(RuntimeException e)
			{
				Log.d("le debug", e.getMessage());
			}
		} 
		else if (item.getItemId() == R.id.menu_delete)
		{
			if(currentMeetingIntent != null)
			{
				locationManager.removeProximityAlert(currentMeetingIntent);
				markersOverlay.removeMeetingMarker();
				mapView.invalidate();
			}
		}
	
		return super.onOptionsItemSelected(item);
	}

	private void updateWithNewLocation(Location location, boolean moveFocus) {

		MapView mapView = (MapView) findViewById(R.id.myMapView);
		MapController controller = mapView.getController();
		if (location != null) {
			GeoPoint g = GeoPointHelper.fromLocation(location);

			if (markersOverlay != null) {
				markersOverlay.updatePositionMarker(g);
				if (moveFocus) {
					controller.animateTo(g);
				}
			}
		}
	}
}
